# Copyright (c) 2005,2006,2007 Dynamic Solutions Inc. (support@dynamic-solutions.com)
#
# This file is part of DataZoomer.
#
# DataZoomer is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DataZoomer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""General purpose utilities"""


from zoom import zoomer

import os

# Handy date values
import datetime
today     = datetime.date.today()
one_day   = datetime.timedelta(1)
one_week  = one_day * 7
one_hour  = datetime.timedelta(hours=1)
one_minute= datetime.timedelta(minutes=1)
yesterday = today - one_day
tomorrow  = today + one_day
now       = datetime.datetime.now()
first_day_of_the_month = datetime.date(today.year,today.month,1)
last_day_of_last_month = first_day_of_the_month - one_day
first_day_of_last_month = datetime.date(last_day_of_last_month.year,last_day_of_last_month.month,1)
last_month = (first_day_of_last_month,last_day_of_last_month)
me        = zoomer.user_id
# one_year, one_hour, one_month, ago, ahead

def message(message):
    if zoomer.session.messages:
        zoomer.session.messages.append(message)
    else:
        zoomer.session.messages = [message]

def warning(message):
    if zoomer.session.warnings:
        zoomer.session.warnings.append(message)
    else:
        zoomer.session.warnings = [message]

def anonymous_bookmark(btext,btitle,**args):
    params = ['app=%s'%args.get('app',zoomer.app.name),'con=%s'%args.get('con',zoomer.webvars.con)]
    for arg_name in args:
        if not arg_name in ['app','con']:
            params.append('%s=%s' % (arg_name,args[arg_name]))
    url = '%s/?%s' % (zoomer.site_url,'&amp;'.join(params))
    link = dzhtml.HtmlTag('a',href=url,title=btitle)
    link.add(btext and btext or url)
    return link

def bookmark(btext,btitle,**args):
    params = ['sid=%s'%args.get('app',zoomer.sid),'app=%s'%args.get('app',zoomer.app.name),'con=%s'%args.get('con',zoomer.webvars.con)]
    for arg_name in args:
        if not arg_name in ['sid','app','con']:
            params.append('%s=%s' % (arg_name,args[arg_name]))
    url = '%s/?%s' % (zoomer.site_url,'&amp;'.join(params))
    link = dzhtml.HtmlTag('a',href=url,title=btitle)
    link.add(btext and btext or url)
    return link

def tag_for(tag_text,content='',*args,**keywords):
    tag_type = tag_text.upper()
    singles = ''.join([' %s' % arg.upper() for arg in args])
    attribute_text = ''.join([' %s="%s"' % (key.upper(),keywords[key]) for key in keywords])
#    attribute_text = ''.join([' %s="%s"' % (key.upper(),keywords[key]) for key in keywords])
#    attribute_text = ''.join([' %s="%s"' % (key.upper(),keywords[key]) for key in keywords])
    if not tag_type in ['BR','HR','INPUT']:
        return '<%s%s%s>%s</%s>' % (tag_type,singles,attribute_text,content,tag_type)
    elif not tag_type in ['INPUT']:
        return '</ %s%s%s>' % (tag_type,singles,attribute_text)
    else:
        return '<%s%s%s>' % (tag_type,singles,attribute_text)

def url_for(**args):
    def get_arg(name,default):
        if name in args:
            return args[name]
        else:
            return default
    sid = get_arg('sid',zoomer.sid)
    app = get_arg('app',zoomer.app.name) or zoomer.app.name
    con = get_arg('con',zoomer.webvars.con)
    params = []
    if not zoomer.use_cookies:
        params.append('sid=%s'%sid)
    params.append('app=%s'%app)
    if con: params.append('con=%s'%con)
    for arg_name in args:
        if not arg_name in ['sid','app','con']:
            params.append('%s=%s' % (arg_name,args[arg_name]))
    return '%s?%s' % (zoomer.main_url,'&'.join(params))

def abs_url_for(**args):
    return url_for(**args)

def link_to(text,title=None,**args):
    return tag_for('a',text,href=url_for(**args))

def form_for(content,**args):
    params = args.copy()
    if not zoomer.use_cookies:
        params.setdefault('sid',zoomer.sid)
    params.setdefault('app',zoomer.app.name)
    if zoomer.app.controller_name:
        params.setdefault('con',zoomer.app.controller_name)
    if (not 'key' in args) and zoomer.webvars.key:
        params.setdefault('key',zoomer.webvars.key)
#    params.setdefault('test','test')
    form_name = args.get('form_name','dz_form')
    t = []
    for arg_name in params:
        t.append('\n<input type=hidden name="%s" value="%s">' % (arg_name,params[arg_name]))
    return '<form action="%s" id="%s" name="%s" method=POST>%s\n%s</form>' % (zoomer.main_url,form_name,form_name,''.join(t),content)

def multipart_form_for(content,**args):
    params = args.copy()
    if not zoomer.use_cookies:
        params.setdefault('sid',zoomer.sid)
    params.setdefault('app',zoomer.app.name)
    params.setdefault('con',zoomer.webvars.con)
    t = []
    for arg_name in params:
        t.append('\n<input type=hidden name="%s" value="%s">' % (arg_name,params[arg_name]))
    return '<form action="%s" method=POST enctype="multipart/form-data">%s\n%s</form>' % (zoomer.main_url,''.join(t),content)

def redirect_to(**args):
    class Redirect:
        def __init__(self,url):
            self.url = url
        def render(self):
            import dzresponse
            return dzresponse.RedirectResponse(self.url)
    return Redirect(args.get('url',abs_url_for(**args)))

def include(filename):
    if not os.path.exists(filename):
        return ''
    else:
        f = open(filename,'r')
        t = f.read()
        f.close()
        return t


def template(template_name=None,**args):
    def get_arg(name,default):
        if name in args:
            return args[name]
        else:
            return default
    con = get_arg('con',zoomer.webvars.con)
    filename = './views/%s/%s.txt' % (con,template_name)
    if not os.path.exists(filename):
        filename = template_name

    if filename:
        f = open(filename,'rb')
        t = f.read()
        f.close()
        return t

def respond(text,*args,**keywords):
    class responder:
        def __init__(self,response):
            self.response = response
        def render(self):
            return self.response
    return responder(text)

def orender(template_name=None,*args,**keywords):
    import qml2
    q = qml2.qml()
    tpl = keywords.get('template',template(template_name))
    t = q.qmltext(tpl)
    if 'obj' in keywords:
        return dzhtml.hFill(t,keywords['obj'])
    return t

def render(template,data=None,*args,**keywords):
    def get_template(filename):
        if os.path.exists(filename):
            f = open(filename,'rb')
            t = f.read()
            f.close()
            return t
        else:
            return filename

    import dzml, dzfill
    tpl = get_template(template)
    t = dzml.dzml(tpl,*args,**keywords)
    return dzfill.fill(t,data)

def render_list(alist,template_name):
    tpl = template(template_name)
    import qml2
    tpl_list = qml2.qml().qml(tpl).values()

    header = body = footer = ''

    n = len(tpl_list)
    if n == 1:
        body   = tpl_list[1]
    elif n == 2:
        header = tpl_list[0]
        body   = tpl_list[1]
    elif n == 3:
        header = tpl_list[0]
        body   = tpl_list[1]
        footer = tpl_list[2]

    result = [header]
    for item in alist:
        result.append(render(template=body,obj=item))
    result.append(footer)
    return ''.join(result)

def how_long_ago(dt):
    if type(dt)==datetime.date:
        d = datetime.datetime(dt.year,dt.month,dt.day)
        diff = datetime.datetime.now() - d
    elif type(dt)==datetime.datetime:
        diff = datetime.datetime.now() - dt
    else:
        diff = datetime.datetime.now() - datetime.datetime.fromtimestamp(dt)

    if diff.days > 365*2:
        return 'over %s years ago' % (diff.days / 365)
    elif diff.days > 365*1.75:
        return 'almost two years ago'
    elif diff.days > 365:
        return 'over a year ago'
    elif diff.days > 60:
        return 'over %s months ago' % (diff.days / 60)
    elif diff.days > 30:
        return 'over a month ago'
    elif diff.days > 14:
        return '%s weeks ago' % (diff.days / 7)
#        return '%s' % (datetime.datetime.now() - diff)
    elif diff.days > 1:
        return '%s days ago' % diff.days
    elif diff.days == 1:
        return 'yesterday'
    elif diff.seconds > 3600:
        return '%s hours ago' % int(diff.seconds / 3600)
    elif diff.seconds > 60:
        return '%s minutes ago' % int(diff.seconds / 60)
    elif diff.seconds > 0:
        return '%s seconds ago' % int(diff.seconds)
    else:
        return 'a moment ago'
    

def ismember(group):
    return zoomer.acl.is_member(zoomer.loginid,group)

def isadmin():
    return ismember(zoomer.admin_group)

def browse(alist,labels=None,on_click=None,on_delete=None,on_remove=None,**args):
    odd_rowclass = 'zrow2'
    evn_rowclass = 'zrow1'

    t = []
    if labels:
        t.append( '<tr>' )

        colnum = 0
        for label in labels:
            colnum += 1
            if colnum == 1:
                t.append('<th class="baselist">%s</th>' % label)
            else:
                t.append('<th class="baselist">%s</th>' % label)
#                t.append('<th class="baselist"><center>%s</center></th>' % label)

#        t += ['<th class="baselist">%s</th>' % label for label in labels]
        if on_delete:
            t.append('<th class="baselist" colwidth=1px>%s</th>' % '')
        if on_remove:
            t.append('<th class="baselist" colwidth=1px>%s</th>' % '')
        t.append( '</tr>' )
        odd_rowclass = 'zrow1' # if there is a header start line shading on 2nd line
        evn_rowclass = 'zrow2'

    count = 0
    for row in alist:
        count += 1
        if count % 2:
            rowclass = evn_rowclass
        else:
            rowclass = odd_rowclass
        t.append( '<tr class=%s>' % rowclass )

        colnum = 0
        for item in row:
            if (on_click or on_delete or on_remove) and colnum == 0:
                key = item
            if on_click and (colnum == 1 or colnum==0 and len(row)==1):
                t.append('<td>%s</td>' % link_to(item,action=on_click,key=key,**args))
            elif colnum>0 or not (on_click or on_remove or on_delete):
                t.append('<td>%s</td>' % item)
            colnum += 1

        if on_delete:
            link = url_for(action=on_delete,key=key,**args)
            t.append('<td width=1px><a href="%s"><img src="<#IMG>delete.png" border=0 height=13px width=13px alt="delete"></a></td>' % link)

        if on_remove:
            link = url_for(action=on_remove,key=key,**args)
            t.append('<td width=1px><a href="%s"><img src="<#IMG>remove.png" border=0 height=13px width=13px alt="remove"></a></td>' % link)

        t.append( '</tr>' )

    result = '\n'.join(['<table class="baselist" width="100%">'] + t + ['</table>'])
    return result



if __name__=='__main__':
    import unittest

    class Tests(unittest.TestCase):
        def test_how_long_ago(self):
            pass

        def test_tag_for(self):
            self.assertEqual(tag_for('option','One','checked',value='one'),
            '<OPTION CHECKED VALUE="one">One</OPTION>')

        def test_ulr_for(self):
            self.assertEqual(url_for(action='this'),'not this')

    unittest.main()



















